﻿using System;
using UnityEngine;
using UnityEngine.Tilemaps;

namespace QFramework.Gun
{
    [DisallowMultipleComponent] // 禁止在同一个游戏对象上添加多个该组件
    [RequireComponent(typeof(BoxCollider2D))] // 要求该组件依赖于 BoxCollider2D 组件
    public class InstantiatedRoom : MonoBehaviour
    {
        [HideInInspector] public Room room; // 当前实例化的房间对象
        [HideInInspector] public Grid grid; // 房间的网格组件
        [HideInInspector] public Tilemap groundTilemap; // 地板层的瓦片地图
        [HideInInspector] public Tilemap decoration1Tilemap; // 装饰层1的瓦片地图
        [HideInInspector] public Tilemap decoration2Tilemap; // 装饰层2的瓦片地图
        [HideInInspector] public Tilemap frontTilemap; // 前景层的瓦片地图
        [HideInInspector] public Tilemap collisionTilemap; // 碰撞层的瓦片地图
        [HideInInspector] public Tilemap minimapTilemap; // 小地图层的瓦片地图
        [HideInInspector] public Bounds roomColliderBounds; // 房间的碰撞边界

        private BoxCollider2D boxCollider2D; // BoxCollider2D 组件的引用

        private void Awake()
        {
            // 获取 BoxCollider2D 组件
            boxCollider2D = GetComponent<BoxCollider2D>();

            // 保存房间碰撞体的边界信息
            roomColliderBounds = boxCollider2D.bounds;
        }

        /// <summary>
        /// 初始化实例化的房间
        /// </summary>
        public void Initialise()
        {
            // 初始化瓦片地图和网格组件成员变量
            PopulateTilemapMemberVariables();

            //关闭未使用的 dorway
            BlockOffUnusedDoorways();
            
            //添加门
            AddDoorsToRooms();
            
            // 禁用碰撞层瓦片地图的渲染器
            DisableCollisionTilemapRenderer();
        }

        /// <summary>
        /// add 门
        /// </summary>
        private void AddDoorsToRooms()
        {
            // if the room is a corridor then return
            if (room.roomNodeType.isCorridorEW || room.roomNodeType.isCorridorNS) return;

            // Instantiate door prefabs at doorway positions
            foreach (Doorway doorway in room.doorWayList)
            {

                // if the doorway prefab isn't null and the doorway is connected
                if (doorway.doorPrefab != null && doorway.isConnected)
                {
                    float tileDistance = 1;

                    GameObject door = Instantiate(doorway.doorPrefab, gameObject.transform);;

                    if (doorway.orientation == Orientation.north)
                    {
                        door.transform.localPosition = new Vector3(doorway.position.x + tileDistance / 2f, doorway.position.y + tileDistance, 0f);
                    }
                    else if (doorway.orientation == Orientation.south)
                    {
                        door.transform.localPosition = new Vector3(doorway.position.x + tileDistance / 2f, doorway.position.y, 0f);
                    }
                    else if (doorway.orientation == Orientation.east)
                    {
                        door.transform.localPosition = new Vector3(doorway.position.x + tileDistance, doorway.position.y + tileDistance * 1.25f, 0f);
                    }
                    else if (doorway.orientation == Orientation.west)
                    {
                        door.transform.localPosition = new Vector3(doorway.position.x, doorway.position.y + tileDistance * 1.25f, 0f);
                    }
                    
                    Door doorComponent = door.GetComponent<Door>();
                    //boss房间锁上
                    if (doorComponent&&room.roomNodeType.isBossRoom)
                    {
                        doorComponent.IsBossRoomDoor = true;
                        doorComponent.LockDoor();
                    }

                }

            }

        }


        /// <summary>
        /// 填充瓦片地图和网格组件的成员变量
        /// </summary>
        private void PopulateTilemapMemberVariables()
        {
            // 获取房间游戏对象中的 Grid 组件
            grid = GetComponentInChildren<Grid>();

            // 获取所有子对象中的 Tilemap 组件
            Tilemap[] tilemaps = GetComponentsInChildren<Tilemap>();

            // 遍历所有 Tilemap 组件，根据标签分类到相应的成员变量中
            foreach (Tilemap tilemap in tilemaps)
            {
                if (tilemap.gameObject.tag == "groundTilemap")
                {
                    groundTilemap = tilemap;
                }
                else if (tilemap.gameObject.tag == "decoration1Tilemap")
                {
                    decoration1Tilemap = tilemap;
                }
                else if (tilemap.gameObject.tag == "decoration2Tilemap")
                {
                    decoration2Tilemap = tilemap;
                }
                else if (tilemap.gameObject.tag == "frontTilemap")
                {
                    frontTilemap = tilemap;
                }
                else if (tilemap.gameObject.tag == "collisionTilemap")
                {
                    collisionTilemap = tilemap;
                }
                else if (tilemap.gameObject.tag == "minimapTilemap")
                {
                    minimapTilemap = tilemap;
                }
            }
        }

        /// <summary>
        /// 禁用碰撞层瓦片地图的渲染器
        /// </summary>
        private void DisableCollisionTilemapRenderer()
        {
            // 禁用碰撞层瓦片地图的 TilemapRenderer 组件
            collisionTilemap.gameObject.GetComponent<TilemapRenderer>().enabled = false;
        }

        #region 关闭未使用的门口

        /// <summary>
        /// 封闭房间中未使用的门口
        /// </summary>
        private void BlockOffUnusedDoorways()
        {
            var tilemaps = new Tilemap[]
            {
                collisionTilemap,
                minimapTilemap,
                groundTilemap,
                decoration1Tilemap,
                decoration2Tilemap,
                frontTilemap
            };

            foreach (var doorway in room.doorWayList)
            {
                if (!doorway.isConnected)
                {
                    foreach (var tilemap in tilemaps)
                    {
                        if (tilemap != null)
                        {
                            BlockADoorwayOnTilemapLayer(tilemap, doorway);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 在指定的瓦片地图层上封闭一个门口
        /// </summary>
        private void BlockADoorwayOnTilemapLayer(Tilemap tilemap, Doorway doorway)
        {
            switch (doorway.orientation)
            {
                case Orientation.north:
                case Orientation.south:
                    BlockDoorwayHorizontally(tilemap, doorway);
                    break;
                case Orientation.east:
                case Orientation.west:
                    BlockDoorwayVertically(tilemap, doorway);
                    break;
                case Orientation.none:
                    break;
            }
        }

        /// <summary>
        /// 水平封闭门口 - 用于北和南方向的门口
        /// </summary>
        private void BlockDoorwayHorizontally(Tilemap tilemap, Doorway doorway)
        {
            Vector2Int startPosition = doorway.doorwayStartCopyPosition;

            for (int xPos = 0; xPos < doorway.doorwayCopyTileWidth; xPos++)
            {
                for (int yPos = 0; yPos < doorway.doorwayCopyTileHeight; yPos++)
                {
                    Vector3Int sourcePos = new Vector3Int(startPosition.x + xPos, startPosition.y - yPos, 0);
                    Vector3Int targetPos = new Vector3Int(startPosition.x + 1 + xPos, startPosition.y - yPos, 0);

                    CopyTileWithTransform(tilemap, sourcePos, targetPos);
                }
            }
        }

        /// <summary>
        /// 垂直封闭门口 - 用于东和西方向的门口
        /// </summary>
        private void BlockDoorwayVertically(Tilemap tilemap, Doorway doorway)
        {
            Vector2Int startPosition = doorway.doorwayStartCopyPosition;

            for (int yPos = 0; yPos < doorway.doorwayCopyTileHeight; yPos++)
            {
                for (int xPos = 0; xPos < doorway.doorwayCopyTileWidth; xPos++)
                {
                    Vector3Int sourcePos = new Vector3Int(startPosition.x + xPos, startPosition.y - yPos, 0);
                    Vector3Int targetPos = new Vector3Int(startPosition.x + xPos, startPosition.y - 1 - yPos, 0);

                    CopyTileWithTransform(tilemap, sourcePos, targetPos);
                }
            }
        }

        /// <summary>
        /// 复制瓦片并设置其变换矩阵
        /// </summary>
        private void CopyTileWithTransform(Tilemap tilemap, Vector3Int sourcePos, Vector3Int targetPos)
        {
            Matrix4x4 transformMatrix = tilemap.GetTransformMatrix(sourcePos);
            tilemap.SetTile(targetPos, tilemap.GetTile(sourcePos));
            tilemap.SetTransformMatrix(targetPos, transformMatrix);
        }

        #endregion

        private void OnTriggerEnter2D(Collider2D other)
        {
            if (other.tag == Settings.playerTag || other.tag == Settings.playerWeapon)
            {
                //触发房间改变事件
                EventCenter.Instance.EventTrigger(EventEnumType.current_room_changed, new CurRoomChanged()
                {
                    currentRoom = room
                });
            }
        }
    }

}